package cn.tedu.wechatdemo.utils;

import cn.tedu.wechatdemo.dto.WeChatDTO;
import lombok.AccessLevel;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import java.security.MessageDigest;
import java.util.Arrays;

/**
 * @Author: Miyako
 * @Date: 2024-10-15-8:30
 * @Description:微信接口工具包
 */

@Slf4j
@FieldDefaults(level = AccessLevel.PRIVATE)
@Data
public class WeChatUtils {
    //自定义token
    String token;
    //时间戳从微信获取
    String timestamp;
    //随机数从微信获取
    String nonce;
    //校验数据
    String signature;
    //随机验证码
    String echostr;

    /**
     * @param: [token, weChatDTO] token是自定义的值，weCharDTO是微信传来的参数
     * @description:工具类构造器
     **/
    public WeChatUtils (String token , WeChatDTO weChatDTO){
        this.token=token;
        timestamp = weChatDTO.getTimestamp();
        nonce = weChatDTO.getNonce();
        signature=weChatDTO.getSignature();
        echostr=weChatDTO.getEchostr();
    }

    /**
     * @return: java.lang.String
     * @description:具体检测方法
     * 1）将token、timestamp、nonce三个参数进行字典序排序
     *
     * 2）将三个参数字符串拼接成一个字符串进行sha1加密
     *
     * 3）开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
     **/
    public String checkWeChatToken() {
        String[] params = {timestamp, nonce, token};
        //字典序排序（本质通过ASCII码排序）
        Arrays.sort(params);
        //排序后组成一个字符串
        String checkStr = String.join("", params);
        MessageDigest digest;
        byte[] bytes = new byte[0];
        try {
            digest = MessageDigest.getInstance("SHA-1");
            //通过SHA-1加密后生成byte数组
            bytes = digest.digest(checkStr.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        StringBuilder hexString = new StringBuilder();
        //将byte数组转化为一个16进制的字符串
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        log.debug("转为16进制字符串后{}", hexString);

        //校验数据是否正常，如果正常返回echostr
        if (signature.equals(hexString.toString())) {
            log.debug("校验成功{}", hexString);
            return echostr;
        }
        log.debug("验证失败");
        return "defeat";

    }
}
